/*-------------------------------------------------------------------------
 *
 * shmem.h
 *	  共享内存管理结构
 *
 * 历史说明：
 * 很久以前，Postgres 的共享内存区域被允许在每个进程中映射到不同的地址，
 * 共享内存“指针”作为相对于共享内存区域起始位置的偏移量传递。
 * 现在情况已不再如此：每个进程必须在相同的地址映射共享内存区域。
 * 这意味着共享内存指针可以在不同进程之间直接传递。
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/storage/shmem.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef SHMEM_H
#define SHMEM_H

#include "utils/hsearch.h"


/* shmqueue.c */
typedef struct SHM_QUEUE
{
	struct SHM_QUEUE *prev;
	struct SHM_QUEUE *next;
} SHM_QUEUE;

/* shmem.c */
extern void InitShmemAccess(void *seghdr);
extern void InitShmemAllocation(void);
extern void *ShmemAlloc(Size size);
extern void *ShmemAllocNoError(Size size);
extern void *ShmemAllocUnlocked(Size size);
extern bool ShmemAddrIsValid(const void *addr);
extern void InitShmemIndex(void);
extern HTAB *ShmemInitHash(const char *name, long init_size, long max_size,
						   HASHCTL *infoP, int hash_flags);
extern void *ShmemInitStruct(const char *name, Size size, bool *foundPtr);
extern Size add_size(Size s1, Size s2);
extern Size mul_size(Size s1, Size s2);

/* ipci.c */
extern void RequestAddinShmemSpace(Size size);

/* shmem 索引表的大小常量 */
 /* 数据结构字符串名称的最大大小 */
#define SHMEM_INDEX_KEYSIZE		 (48)
 /* shmem 索引表的预计大小（不是硬限制） */
#define SHMEM_INDEX_SIZE		 (64)

/* 这是 shmem 索引表中的一个哈希桶 */
typedef struct
{
	char		key[SHMEM_INDEX_KEYSIZE];	/* 字符串名称 */
	void	   *location;		/* 在共享内存中的位置 */
	Size		size;			/* 请求的结构的字节数 */
	Size		allocated_size; /* 实际分配的字节数 */
} ShmemIndexEnt;

/*
 * shmqueue.c 中函数的原型
 */
extern void SHMQueueInit(SHM_QUEUE *queue);
extern void SHMQueueElemInit(SHM_QUEUE *queue);
extern void SHMQueueDelete(SHM_QUEUE *queue);
extern void SHMQueueInsertBefore(SHM_QUEUE *queue, SHM_QUEUE *elem);
extern void SHMQueueInsertAfter(SHM_QUEUE *queue, SHM_QUEUE *elem);
extern Pointer SHMQueueNext(const SHM_QUEUE *queue, const SHM_QUEUE *curElem,
							Size linkOffset);
extern Pointer SHMQueuePrev(const SHM_QUEUE *queue, const SHM_QUEUE *curElem,
							Size linkOffset);
extern bool SHMQueueEmpty(const SHM_QUEUE *queue);
extern bool SHMQueueIsDetached(const SHM_QUEUE *queue);

#endif							/* SHMEM_H */
